package nachos.threads;
import nachos.ag.BoatGrader;
import java.util.ArrayList;
import java.util.Iterator;

public class Boat
{

  public static BoatGrader bg = new BoatGrader();

  public static final int OAHU = 1; //indicate side value for OAHU
  public static final int MOLOKAI = 2; //indicate side value for MOLOKAI
 
  private static int side = OAHU; //indicate start on OAHU
  public static boolean empty = true; //indicate boat starts empty

  private static ArrayList<KThread> adultThreads = new ArrayList<KThread>(); //holds adult threads
  private static ArrayList<KThread> childThreads = new ArrayList<KThread>(); //holds child threads

  public static Lock condlock = new Lock();
  public static boolean condstate = false;
  public static Condition condition = new Condition( condlock );

  public static Semaphore childMutex = new Semaphore(0);
  
  /**
   * run through tests to see solution with varying numbers of adults and children
   */
  public static void selfTest()
  {
    System.out.println("\n ***Testing Boats with only 2 children***"); begin(0, 2);

    System.out.println("\n ***Testing Boats with 2 children, 1 adult***"); begin(1, 2);

    System.out.println("\n ***Testing Boats with 3 children, 3 adults***"); begin(3, 3);
  }

  /**
   * runs the simulation
   */
  public static void begin( int adults, int children )
  {
     bg = new BoatGrader();
     side = OAHU;
     empty = true;
     adultThreads = new ArrayList<KThread>();
     childThreads = new ArrayList<KThread>();
     KThread lastThread = null;
     WorldStateListener.reset();
    // Create threads here. See section 3.4 of the Nachos for Java
    // Walkthrough linked from the projects page.
    for(int i=1; i<=adults; i++)
    {
      KThread aThread = new KThread( new Adult() );
      aThread.setName("Adult " + i);
      System.out.println( "Starting Adult " + i );
      aThread.fork();
      adultThreads.add(aThread);
    }

    for(int i=1; i<=children; i++)
    {
      KThread cThread = new KThread( new Child() );
      lastThread = cThread;
      cThread.setName("Child " + i);
      System.out.println( "Starting Child " + i );
      cThread.fork();
      childThreads.add(cThread);
    }

    lastThread.join();
	
	/*for(KThread t : childThreads)
	{
		t.join();
	}

	for(KThread t : adultThreads)
	{
		t.join();
	}*/
  }

  /**
   * @return true if boat is empty
   */
  public static boolean isEmpty() {
     return empty;
  }

  /**
   * @return either Boat.OAHU or Boat.MOLOKAI
   */
  public static int side() {
     return side;
  }

  /**
   * change the boat indicator to the other island when a person crosses
   */
  public static void cross() {
     if( side == OAHU ) {
        side = MOLOKAI;
     } else {
        side = OAHU;
     }
     empty = true;
  }

}
